package com.egreen.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egreen.common.States;
import com.egreen.common.pojo.DTO.asset.OperatePointRecordingDTO;
import com.egreen.common.pojo.entity.user.*;
import com.egreen.common.pojo.DTO.user.userServiceDTO.ApplicationForAgencyDTO;
import com.egreen.common.pojo.DTO.user.userServiceDTO.CompleteInformationDTO;
import com.egreen.common.pojo.DTO.user.userServiceDTO.SignUpDTO;
import com.egreen.common.serviceapi.asset.IAssetServiceApi;
import com.egreen.common.serviceapi.system.VerificationCodeAPI;
import com.egreen.common.serviceapi.user.IUserServiceApi;
import com.egreen.user.exceptions.UserException;
import com.egreen.user.dao.AgentApplicationDao;
import com.egreen.user.service.*;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLClientInfoException;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cloudJiang
 * @since 2022-07-26
 */
@Service
public class AgentApplicationServiceImpl extends ServiceImpl<AgentApplicationDao, AgentApplication> implements IAgentApplicationService {

    @Autowired
    IUserStatesService userStatesService;

    @Autowired
    IAgentApplicationService agentApplicationService;

    @Autowired
    IAgentAreaService agentAreaService;

    @Autowired
    IHistoryLocationDetailService historyLocationDetailService;

    @Autowired
    IUserHistoryLocationService userHistoryLocationService;

    @Autowired
    IUserLoginAccountService loginAccountService;

    @Lazy
    @Autowired
    IUserService userService;

    @Autowired
    IUserLocationService userLocationService;

    @Autowired
    ILocationDetailService locationDetailService;

    @Autowired
    IInvitedService iInvitedService;

    @DubboReference
    IAssetServiceApi assetServiceApi;

    @DubboReference
    VerificationCodeAPI verificationCodeAPI;

    @DubboReference
    IUserServiceApi userServiceApi;


    @Override
    @Transactional(rollbackFor = {SQLClientInfoException.class, UserException.class})
    public void applicationForAgency(ApplicationForAgencyDTO applicationForAgencyDTO) {
        boolean isNewUser;

        //查询手机号是否已存在
        QueryWrapper<UserLoginAccount> phonewrapper = new QueryWrapper<>();
        phonewrapper.eq("phone", applicationForAgencyDTO.getPhone());
        UserLoginAccount loginAccount = loginAccountService.getOne(phonewrapper);
        isNewUser = loginAccount == null;
        Long userID;

        if (isNewUser) {
            //如果是新用户则直接写入数据库
            //准备注册以及信息完善的dto
            SignUpDTO signUpDTO = new SignUpDTO();
            applicationForAgencyDTO.setAgencyType(applicationForAgencyDTO.getAgencyType());

            BeanUtils.copyProperties(applicationForAgencyDTO, signUpDTO);

            CompleteInformationDTO completeInformationDTO = new CompleteInformationDTO();

            BeanUtils.copyProperties(applicationForAgencyDTO, completeInformationDTO);

            userID = userService.signUp(signUpDTO);
            completeInformationDTO.setUserID(userID);
            userService.completeInformation(completeInformationDTO);
        } else {
            //如果是老用户则将收到的数据更新至数据库
            //通过登录信息获取用户id
            QueryWrapper<User> userwrapper = new QueryWrapper<>();
            userwrapper.eq("login_account_id", loginAccount.getId());
            User user = userService.getOne(userwrapper);
            userID = user.getId();

            //获取用户位置信息
            QueryWrapper<UserLocation> locationQueryWrapper = new QueryWrapper<>();
            locationQueryWrapper.eq("id", user.getLocationId());
            UserLocation userLocation = userLocationService.getOne(locationQueryWrapper);

            QueryWrapper<LocationDetail> locationDetailWrapper = new QueryWrapper<>();
            locationDetailWrapper.eq("id", userLocation.getDetailId());
            LocationDetail locationDetail = locationDetailService.getOne(locationDetailWrapper);

            //将原地址信息备份至数据库
            HistoryLocationDetail historyLocationDetail = new HistoryLocationDetail();
            historyLocationDetail.setDistrict(locationDetail.getDistrict());
            historyLocationDetail.setCommunity(locationDetail.getCommunity());
            historyLocationDetail.setLocationDetails(locationDetail.getLocationDetails());
            historyLocationDetailService.save(historyLocationDetail);

            UserHistoryLocation userHistoryLocation = new UserHistoryLocation();
            userHistoryLocation.setUserId(userID);
            userHistoryLocation.setCountryId(1);
            userHistoryLocation.setProvinceId(userLocation.getProvinceId());
            userHistoryLocation.setCityName(userLocation.getCityName());
            userHistoryLocation.setDetailId(historyLocationDetail.getId());
            userHistoryLocationService.save(userHistoryLocation);
        }

        //查找是否存在申请记录
        QueryWrapper<AgentApplication> agentWrapper = new QueryWrapper();
        agentWrapper.eq("user_id", userID);
        agentWrapper.eq("state", "申请中");
        AgentApplication historyApplication = agentApplicationService.getBaseMapper().selectOne(agentWrapper);
        //不存在则插入申请记录
        if (historyApplication == null) {
            //将用户的申请数据存入数据库
            AgentApplication agentApplication = new AgentApplication();
            agentApplication.setState("申请中");
            agentApplication.setLevel(applicationForAgencyDTO.getAgencyType());
            agentApplication.setUserId(userID);
            agentApplicationService.save(agentApplication);
        } else {
            throw new UserException(50000, "申请正在处理，请耐心等待");
        }



        /* todo  应该在代理申请通过后再存储代理位置信息，故以下注释代码应该更改位置*/
        /*//存储用户代理位置信息
        AgentArea agentArea = new AgentArea();
        agentArea.setAgentApplicationId(agentApplication.getId());
        String area = completeInformationDTO.getProvince() + "-" + completeInformationDTO.getCity()
                + "-" + completeInformationDTO.getDistrict() + "-" + completeInformationDTO.getCommunity()
                + "-" + completeInformationDTO.getLocationDetails();
        agentArea.setArea(area);
        agentArea.setLevel(userStates.getStates());
        agentArea.setState(0);
        agentAreaService.save(agentArea);*/

        //判断用户是否填写了正确的邀请码，如果填写则为邀请者增加邀请人数和资产（积分等）
        if (applicationForAgencyDTO.getInvitationCode() != null && !applicationForAgencyDTO.getInvitationCode().equals("")) {
            QueryWrapper<User> inviterWrapper = new QueryWrapper<>();
            inviterWrapper.eq("invitation_code", applicationForAgencyDTO.getInvitationCode());
            User inviter = userService.getOne(inviterWrapper);

            if (inviter == null) {
                throw new UserException(States.ERR_UNIQUE.getStates(), "邀请码不存在");
            } else {
                inviter.setInvitedNumber(inviter.getInvitedNumber() + 1);
                userService.updateById(inviter);

                //增加一条邀请记录
                Invited invited = new Invited();
                invited.setInviteUserId(inviter.getId());
                invited.setInvitedUserId(userID);
                iInvitedService.save(invited);

                //为邀请者增加积分
                int num = 50;
                OperatePointRecordingDTO operatePointRecordingDTO = new OperatePointRecordingDTO();
                operatePointRecordingDTO.setId(inviter.getId());
                operatePointRecordingDTO.setPointAccountId(inviter.getPointAccountId());
                operatePointRecordingDTO.setOperate("增加");
                operatePointRecordingDTO.setOperatePointNum(num);
                assetServiceApi.updateByPoint(operatePointRecordingDTO);
            }
        }
    }
}
